<template>
  <z-modal
    :title="title"
    v-bind="modalOption"
    :bodyStyle="{minHeight:'500px','padding-top':'0px'}"
    @cancel="handleCancel"
  >
    <template slot="footer">
      <div style="text-align:center;">
        <a-button @click="handleCancel">关闭</a-button>
        <a-button type="primary" v-if="type === 'handling'" :loading="confirmLoading" @click="handleComplete">同意</a-button>
        <a-button type="danger" v-if="type === 'handling'" ghost :loading="confirmLoading" @click="handleRejectLast">驳回上一节点</a-button>
        <a-button type="danger" v-if="type === 'handling'" :loading="confirmLoading" @click="handleRejectFirst">不同意</a-button>
        <a-button type="primary" v-if="type === 'handling'" :loading="confirmLoading" @click="handleDelegate">委派</a-button>
        <a-button type="primary" v-if="type === 'claim'" :loading="confirmLoading" @click="handleClaim">拾取</a-button>
        <a-button type="danger" v-if="hasCancel" :loading="confirmLoading" @click="handleTaskCancel">撤回</a-button>
      </div>
    </template>
    <a-spin :spinning="confirmLoading">
      <a-tabs  tab-position="left">
        <a-tab-pane key="1">
          <span slot="tab">
            <a-icon type="file" />
            表单信息
          </span>
          <a-collapse v-model="activeKey" class="!mt-4">
            <a-collapse-panel key="1" header="发起单据">
              <KFormBuild class="k-form-design" ref="kfbStart" :dynamicData="dynamicDataSatrt" disabled  :value="formModel" />
            </a-collapse-panel>
            <a-collapse-panel key="2" header="待办单据" v-if="task.hasForm &&  type !== 'history'">
              <TaskForm class="k-form-design" ref="kfbPend" :task="task" :formData="formData" :nodeId="task.taskDefinitionKey" />
            </a-collapse-panel>
          </a-collapse>
        </a-tab-pane>
        <a-tab-pane key="2">
          <span slot="tab">
            <a-icon type="share-alt" />
            办理进度
          </span>
          <bpmnTaskViewer :nodeCodes="nodeCodes" :activityList="nodeDatas" :xml="flowDef.source"/>
        </a-tab-pane>
        <a-tab-pane key="3" >
          <span slot="tab">
            <a-icon type="history" />
            办理记录
          </span>
          <TaskHistory :processInstanceId="task.processInstanceId" :task="task" :formData="formData" />
        </a-tab-pane>
      </a-tabs>
    </a-spin>
    <DelegateModal ref="delegateModal"  @ok="success" />
    <CommentModal ref="commentModal"  @ok="commentOk" />
  </z-modal>
</template>

<script>
import ModalMixins from '@/mixins/ModalMixins'
import { postAction, getAction } from '@/services/manage'
import { KFormBuild } from '@/components/k-form-design/packages/use.js'
import bpmnTaskViewer from '@/components/bpmn/bpmnTaskViewer'
import TaskHistory from './TaskHistory'
import TaskForm from './TaskForm'
import { getSelectDictCode, getSelectOptions } from '@/utils/k-form-design'
import DelegateModal from './DelegateModal'
import CommentModal from './CommentModal'
export default {
  name: 'TaskPendingModal',
  components: { KFormBuild, bpmnTaskViewer, TaskHistory, TaskForm, DelegateModal, CommentModal },
  mixins: [ModalMixins],
  props: {
    type: String, // handling:办理 || claim:拾取 || history:审核历史
    hasCancel: { // 是否可撤回
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      url: {
        flowDef: '/camunda/process/details/',
        complete: '/camunda/task/complete/', // 审核通过
        rejectlast: '/camunda/task/reject/last/', // 退回上一节点
        rejectfirst: '/camunda/task/reject/first/', // 退回发起人
        claim: '/camunda/task/claim/', // 拾取
        historics: '/camunda/task/historics/', // 审批流程数据
        active: '/camunda/task/active/',
        cancel: '/camunda/process/cancel/'
        // taskData: '/camunda/task/form/data/'
      },
      formModel: { }, // 表单设计model
      task: {}, // 任务信息
      formDef: {}, // 表单设计信息
      flowDef: {}, // 流程设计信息
      formData: {}, // 表单数据信息
      title: '流程办理',
      activeKey: ['1', '2'],
      dynamicDataSatrt: {},
      hasTaskForm: true,
      nodeCodes: {
        success: [],
        pending: [],
        error: []
      },
      nodeDatas: [],
      rejectType: ''
    }
  },
  methods: {
    async show(task) {
      // this.task = task
      this.visible = true
      this.task = task
      await this.getflowForm(task)
      this.getHistorics()
      // this.getTaskData()
    },
    // taskFormInit(hasTaskForm) {
    //   this.hasTaskForm = hasTaskForm
    // },
    handleComplete() { // 签核
      this.confirmLoading = true
      if (this.hasTaskForm && this.$refs.kfbPend) { // 当前节点有节点表单
        this.$refs.kfbPend.getData().then(values => {
          console.log('验证通过', values)
          this.complete(values)
        }).catch(() => {
          this.confirmLoading = false
          console.log('验证未通过，获取失败')
        })
      } else { // 当前节点无节点表单
        this.complete({})
      }
    },
    async complete(data) {
      const res = await postAction(this.url.complete + this.task.id, data)
      if (res.success) {
        this.$message.success('办理成功')
        // 自定义业务表单 ，签核完成后，更新业务单据流程状态 -- begin
        if (res.result.state === 'COMPLETED') {
          this.updateBpmnStatus('COMPLETED')
        }
        this.confirmLoading = false
        // 自定义业务表单 ，签核完成后，更新业务单据流程状态 -- end
        this.success()
      }
    },
    handleRejectLast() { // 驳回上一节点
      this.rejectType = 'rejectLast'
      this.$refs.commentModal.show()
      // if (this.hasTaskForm && this.$refs.kfbPend) {
      //   this.$refs.kfbPend.getData().then(values => {
      //     console.log('验证通过', values)
      //     this.rejectLast(values)
      //   }).catch(() => {
      //     console.log('验证未通过，获取失败')
      //     this.confirmLoading = false
      //   })
      // } else {
      //   this.rejectLast({})
      // }
    },
    async rejectLast(data) {
      this.confirmLoading = true
      const res = await postAction(this.url.rejectlast + this.task.id, data)
      if (res.success) {
        this.$message.success('驳回上一节点成功')
        this.success()
      }
      this.confirmLoading = false
    },
    handleRejectFirst() { // 驳回开始节点
      this.rejectType = 'rejectFirst'
      this.$refs.commentModal.show()
      // if (this.hasTaskForm && this.$refs.kfbPend) {
      //   this.$refs.kfbPend.getData().then(values => {
      //     console.log('验证通过', values)
      //     this.rejectFirst(values)
      //   }).catch(() => {
      //     this.confirmLoading = false
      //     console.log('验证未通过，获取失败')
      //   })
      // } else {
      //   this.rejectFirst({})
      // }
    },
    commentOk(data) {
      if (this.rejectType === 'rejectFirst') {
        this.rejectFirst(data)
      } else if (this.rejectType === 'rejectLast') {
        this.rejectLast(data)
      }
    },
    async rejectFirst(data) { //
      this.confirmLoading = true
      const res = await postAction(this.url.rejectfirst + this.task.id, data)
      if (res.success) {
        this.$message.success('操作成功')
        this.updateBpmnStatus('INTERNALLY_TERMINATED')
        this.success()
      }
      this.confirmLoading = true
    },
    handleDelegate() { // 委派
      this.$refs.delegateModal.show(this.task)
    },
    handleClaim() {
      this.confirmLoading = true
      postAction(this.url.claim + this.task.id).then(res => {
        if (res.success) {
          this.$message.success('操作成功')
          this.success()
        }
        this.confirmLoading = false
      })
    },
    handleTaskCancel() { // 撤回
      getAction(`${this.url.cancel}${this.task.id}`).then(res => {
        if (res.success) {
          this.$message.success('操作成功')
          this.updateBpmnStatus('INTERNALLY_CANCEL')
          this.success()
        }
        this.confirmLoading = false
      })
    },
    success() {
      this.close()
      this.$emit('ok')
    },
    updateBpmnStatus(state) { // 自定义业务表单 ，签核完成后，更新业务单据流程状态
      this.$refs.kfbStart.updateBpmnStatus && this.$refs.kfbStart.updateBpmnStatus({ task: this.task, formData: this.formData, state: state })
    },
    async getflowForm(task) { // 根据流程定义id获取绑定表单-发起单据及流程
      try {
        this.confirmLoading = true
        const res = await getAction(this.url.flowDef + task.processInstanceId)
        if (!res.success) {
          this.confirmLoading = false
          return this.$message.warning('未查询到发起表单')
        }
        const formModel = res.result.startFormModelDef && res.result.startFormModelDef.model && JSON.parse(res.result.startFormModelDef.model)

        // 必须在渲染前获取到dynamicData --start
        let dictCodes = getSelectDictCode(formModel.list)
        dictCodes = Array.from(new Set(dictCodes))
        this.dynamicDataSatrt = await getSelectOptions(dictCodes)
        // -- end

        // formModel.list = replaceFormModel(formModel.list)

        this.formModel = formModel
        this.flowDef = res.result
        this.formDef = res.result.formModelDef
        this.formData = res.result.startDatas

        this.$nextTick(() => {
          const startDatas = res.result.startDatas
          Object.keys(startDatas).forEach(key => {
            this.isJsonString(startDatas[key]) ? startDatas[key] = JSON.parse(startDatas[key]) : ''
          })
          this.$refs.kfbStart.setData(startDatas)
        })
        this.confirmLoading = false
      } catch (error) {
        this.confirmLoading = false
      }
    },
    isJsonString(str) {
      try {
        const toObj = JSON.parse(str) // json字符串转对象
        /*
          判断条件
          1. 排除null可能性
          2. 确保数据是对象或数组
        */
        if (toObj && typeof toObj === 'object') {
          return true
        }
      } catch {
        // console.error('err')
        return false
      }
      return false
    },
    async getHistorics() { // 获取历史审批节点
      try {
        this.confirmLoading = true
        const res = await getAction(this.url.historics + this.task.processInstanceId)
        const res2 = await getAction(this.url.active + this.task.processInstanceId)
        this.confirmLoading = false
        this.nodeDatas = [].concat(res.result, res2.result)
        this.setFlowNodeStatus(res.result)
        this.setFlowNodePending(res2.result)
        // this.type !== 'history' && this.setFlowNodePending(this.task)
      } catch (error) {
        this.confirmLoading = false
      }
    },
    async getTaskData() {
      const res = await getAction(this.url.taskData + this.task.id)
      console.log(res)
    },
    setFlowNodeStatus(data) { // 获取已审批流程节点状态
      const completed = []
      const error = []
      data.forEach(item => {
        // 移除重复办理节点，以最后一次为准 -begin
        if (completed.includes(item.activityId)) {
          completed.splice(completed.indexOf(item.activityId), 1)
        }
        if (error.includes(item.activityId)) {
          error.splice(error.indexOf(item.activityId), 1)
        }
        // 移除重复，以最后一次为准 - end
        if (item.canceled) {
          error.push(item.activityId)
          // this.nodeDatas.push(item)
        } else {
          // this.nodeDatas.push(item)
          completed.push(item.activityId)
        }
      })
      this.$set(this.nodeCodes, 'completed', completed)
      this.$set(this.nodeCodes, 'error', error)
    },
    setFlowNodePending(data) { // 获取已审批流程节点状态
      const pending = []
      data.forEach(item => {
        // 移除重复办理节点，以最后一次为准 -begin
        if (this.nodeCodes.completed.includes(item.taskDefinitionKey)) {
          this.nodeCodes.completed.splice(this.nodeCodes.completed.indexOf(item.taskDefinitionKey), 1)
        }
        if (this.nodeCodes.error.includes(item.taskDefinitionKey)) {
          this.nodeCodes.error.splice(this.nodeCodes.error.indexOf(item.taskDefinitionKey), 1)
        }
        // this.nodeDatas.push(item)
        // 移除重复，以最后一次为准 - end
        pending.push(item.taskDefinitionKey)
      })
      this.$set(this.nodeCodes, 'pending', pending)
    }
  }
}
</script>
